記得我第一次正式的串接API的時候,踏著愉悅的心想說自己要成為一個真正的前端要來串接了~~~ 結果寫了對應的程式打API之後,資料沒有出來,還馬上在console裏收到一個紅紅的錯
這個問題通常因為放到正式環境又沒問題了,或者直接拍出大絕請後端開好開滿,把 Access-Control-Allow-Origin: *
設定完成,幾乎就解決問題了~
沒錯,如果你只想30秒解決這個問題,告訴你一個快速的結論:
請後端工程師,在API的header加上這個設定屬性Access-Control-Allow-Origin: *
但只要這樣就夠了嗎?身為一個追根究底的工程師,我們應該知道為什麼會有這個問題吧!或是如果在本機開發遇到這個狀況該怎麼處理?或是知道之後才方便之後被面試問到的時候不會答不出來吧(?)
好啦,有這麼多理由該知道,那我們就開始吧!
其實錯誤訊息裡就告訴你為什麼了
access to XMLHttpRequest at 連結A from origin 連結B has been blocked by CORS policy: response to preflight request doesn't pass access control check: No 'Access-control-allow-origin' header is present on the requested resource
當你要從連結B要request到連結A時,被CORS的政策擋下來了,冒號後面告訴你原因:因為preflight request沒有通過存取檢測,請檢查看看request的來源的header有沒有access-control-allow-origin。
實務上就是我的前台網站在 連結A 但需要透過API 連結B 時,前後台兩者網址不同來源,但前台要取得不同來源的資料時,若沒有做好相關的設定就會出現上面的錯誤
錯誤訊息好像每個字都看得懂,但CORS是什麼意思?又為什麼要有CORS? header要加的這個又是什麼呢?接下來讓我們繼續看下去~
在開始CORS之前,我們需要先知道瀏覽器的Same Origin Policy(同源政策)。
瀏覽器基於安全性的考量,規定當你的網站要呼叫API時,需要是同一個來源。
如果是不同來源,瀏覽器依然會幫你發出request,但會把收到的response阻擋起來不給你的網站。
那什麼叫同一個來源呢?
當兩個網址的 schema(protocol) + host + port 皆相同,就是同源(Same-Origin),只要有一者不同,就是跨來源(Cross-origin)
以下舉幾個範例:
來源1 | 來源2 | 結論 |
---|---|---|
http://www.abc.com.tw | https://www.abc.com.tw | 跨來源,schema不同 |
http://www.abc.com.tw | http://www.api.abc.com.tw | 跨來源,host不相同 |
http://www.abc.com.tw:8080 | http://www.abc.com.tw:4200 | 跨來源,port不相同 |
http://www.abc.com.tw/web:8080 | http://www.abc.com.tw/api:8080 | 同源 |
了解了同源、跨來源後,你應該接下來馬上會想到... 怎麼可能我要打的API都是同一個來源呢?如果就是不同源該則麼辦?
CORS = 跨來源資源共用(Cross-Origin Resource Sharing (CORS))。
跨來源資源共用 : 發出request的來源不同,但需要共用資源
可以把API request想像成大樓裡的一個個部門辦公室,有各自的門禁卡。資訊部的人不能進到行銷部,因為他們是不同來源。那如果最近資訊部跟行銷部密切合作,希望可以讓資訊部的人直接進到行銷部怎麼辦?這時候瀏覽器就是這個開啟門禁卡權限的管理員,要開啟門禁權限的方法就是CORS
簡單來說,要開啟不同來共享資源的方式就是:透過在API的response中加入新的http header讓瀏覽器透過這些資訊,來決定要不要放行這個response。
我們已經簡單的知道為什麼我們會遇到這個問題了,那要怎麼加上新的http header當作跨來源的通行證? 又詳細的運作原理是什麼呢?待明天揭曉~